#include "evm_module.h"
#include <stdbool.h>

evm_val_t http_msg_hander(evm_t * e,void *msg) {
    http_response_t *msgbuff = (http_response_t *)msg;

    evm_val_t *args = evm_list_create(e, GC_LIST, 3);
    evm_val_t *buffer = NULL;
    if(msgbuff->data!=NULL ){
        if(strcmp(msgbuff->responseType, "blob") == 0 || strcmp(msgbuff->responseType, "arrayBuffer") == 0){
            int len = msgbuff->data->len;
            buffer = evm_buffer_create(e, len);
            if(buffer != NULL){
                char *addr = (char *)evm_buffer_addr(buffer);
                memcpy(addr, msgbuff->data, len);
            }
        }else{
            buffer = evm_heap_string_create(e, msgbuff->data->data, 0);
        }
        if(buffer == NULL){
            evm_list_set(e, args, 0, EVM_VAL_UNDEFINED);
        }else{
            evm_list_set(e, args, 0, *buffer);
        }
    }else
        evm_list_set(e, args, 0, EVM_VAL_UNDEFINED);

    evm_list_set(e, args, 1, evm_mk_number(msgbuff->code));

    if(msgbuff->header!=NULL){
        evm_val_t *header = evm_heap_string_create(e, msgbuff->header->data, 0);
        if(header == NULL){
            evm_list_set(e, args, 2, EVM_VAL_UNDEFINED);
        }
        evm_list_set(e, args, 2, *header);
    }
    return *args;
}

void http_msg_free(void *msg) {
    http_response_t *msgbuff = (http_response_t *)msg;

    if(msgbuff->data!=NULL){
        if(msgbuff->data->data!= NULL){
            evm_free(msgbuff->data->data);
        }
        evm_free(msgbuff->data);
    }

    if(msgbuff->header!=NULL){
        if(msgbuff->header->data!= NULL){
            evm_free(msgbuff->header->data);
        }
        evm_free(msgbuff->header);
    }

    evm_free(msg);
    msg = NULL;
}

/**
 * @brief evm_module_http_request
 * @param method        请求方式
 * @param url           地址
 * @param header        请求头
 * @param data          请求内容
 * @param responseType  请求数据类型
 * @param timeout       超时时间
 * @param id            JS对象ID
 * @return
 */
static int evm_module_http_request(const char* method, const char* url, const char *header, const char * data, const char *responseType, int timeout, int id)
{
    if( method == NULL || url == NULL){
        return -1;
    }

    evm_event_msg_t *msg = evm_module_msg_create();

    msg->id = id;
    msg->event = "recv";
    msg->cb = http_msg_hander;
    msg->free = http_msg_free;

    http_response_t *resp = evm_malloc(sizeof (http_response_t));
    resp->data = NULL;
    resp->header = NULL;
    resp->code = -1;
//    resp->data = evm_malloc(sizeof (msg_buffer_t));
//    if(resp->data == NULL)
//        return -1;
//    resp->data->data = evm_malloc(WEBCLIENT_RESPONSE_BUFSZ);
//    memset(resp->data->data, 0, WEBCLIENT_RESPONSE_BUFSZ);
//    resp->data->len = 0;

//    resp->header = evm_malloc(sizeof (msg_buffer_t));
//    if(resp->header == NULL)
//        return -1;
//    resp->header->data = evm_malloc(WEBCLIENT_HEADER_BUFSZ);
//    memset(resp->header->data, 0, WEBCLIENT_HEADER_BUFSZ);
//    resp->header->len = 0;

    if(responseType!= NULL){
        int len = strlen(responseType);
        resp->responseType = evm_malloc(len);
        memcpy(resp->responseType, responseType, len);
        resp->responseType[len] = 0;
    }else
        resp->responseType = "text";

    msg->data = resp;

    return evm_adaptor_http_request(strlwr((char *)method),
                            (char *)url,
                            (char *)header,
                            (char *)data,
                            (char *)responseType,
                            timeout,
                            msg);
}



evm_err_t evm_module_http(evm_t *e) {
	if(evm_module_http_init()!=0)
		return ec_memory;
	
    evm_cffi_t funcs[] = {
        {"request", (intptr_t)evm_module_http_request, "isssssii"},
        {NULL, 0, NULL}
    };
    evm_builtin_t builtin[] = {
        {NULL, EVM_VAL_UNDEFINED}
    };
    evm_module_effi_create(e, "@native.http", funcs , builtin);
    return e->err;
}


